/*
 * @author: pwz（潘文周）
 * @description: 多屏联动
 */
let PickerHelper = agcim.interactive.PickerHelper;
let AGScene = agcim.scene.Scene;
class Linkage {
  constructor(mainViewer, secondViewer, mapContainerElement, sliderElement) {
    //主屏幕
    this._mainViewer = mainViewer;
    //副屏幕
    this._secondViewer = secondViewer;
    this.model = Linkage.MODEL_TYPE.COPY;
    //默认左边3d场景右边也是3d场景
    this.scneneModel = Linkage.SCENE_MODEL.SCENE_3D_3D;
    //是否从主屏复制到副屏
    this.mainToSecond = true;
    //为屏幕添加监听，以鼠标所在屏幕为主
    this._mainPickHelper = new PickerHelper(this._mainViewer);
    this._addMoveListener(this._mainPickHelper, true);
    this._secondPickHelper = new PickerHelper(this._secondViewer);
    this._addMoveListener(this._secondPickHelper, false);
    //视角同步的间隔ms
    this.linkInterval = 20;
    this._copyTimer = undefined;
    this._sliderElement = sliderElement;
    this._mapContainerElement = mapContainerElement;
    //卷帘鼠标事件
    this._mouseDownListener = () => {
      this._mapContainerElement.style.overflow = "auto";
      //鼠标在滑块上按下时开始监听移动位置
      window.addEventListener("mousemove", this._mouseMoveListener);
    };
    this._mouseUpListener = () => {
      this._mapContainerElement.style.overflow = "hidden";
      window.removeEventListener("mousemove", this._mouseMoveListener);
    };
    window.addEventListener("resize", this._resizeListener);
    //结束飞行
    mainViewer.scene.camera.completeFlight();
    this._copyCamera(mainViewer, secondViewer);
  }

  _resizeListener() {
    this.setModel(this.model);
  }
  /**
   * @lastUpdateBy : 张瀚
   * @description: 设置移动监听事件，用于调整位置标记的位置
   * @param {*} viewer
   * @param {*} pickerHelper
   * @param {*} mainToSecondValue
   * @return {*}
   */
  _addMoveListener(pickerHelper, mainToSecondValue) {
    pickerHelper.on("MOUSE_MOVE", (event) => {
      if (this._positionIndicatorID && this.mainToSecond != mainToSecondValue) {
        //显示另一个位置的标记，隐藏这边的标记
        let entity = this._mainViewer.entities.getById(
          this._positionIndicatorID
        );
        entity && (entity.show = !mainToSecondValue);
        entity = this._secondViewer.entities.getById(this._positionIndicatorID);
        entity && (entity.show = mainToSecondValue);
      }
      this.mainToSecond = mainToSecondValue;
      this._lastEndPosition = event.endPosition;
    });
  }

  /**
   * @lastUpdateBy : 张瀚
   * @description: 设置同步状态。
   * @param {*} model
   * @return {*}
   */
  setModel(model) {
    //TODO:异步执行，先结束主屏飞行状态
    setTimeout(() => {
      if (!Object.values(Linkage.MODEL_TYPE).includes(model)) {
        throw "无效的模式，请使用本类对象stateMap中的状态值";
      }
      //结束飞行
      // this._mainViewer.scene.camera.completeFlight();
      // this._secondViewer.scene.camera.completeFlight();
      this.model = model;
      switch (model) {
        case Linkage.MODEL_TYPE.COPY:
          //屏幕复制，不做其他事情
          this._startCopyTimer();
          break;
        case Linkage.MODEL_TYPE.SPLIT_SCREEN:
          //分屏，左右的那种
          this._startCopyTimer();
          //左右分屏
          this._mainViewer._element.parentNode.parentNode.style.width = "50%";
          this._secondViewer._element.parentNode.style.width =
            this._mainViewer._element.parentNode.offsetWidth + "px";
          this._sliderElement.style.display = "none";
          this.resetDom();
          break;
        case Linkage.MODEL_TYPE.ROLL:
          //卷帘，重叠然后上方的第二viewer可以拖动改变宽度
          this._startCopyTimer();
          this.setPositionLabel();
          this._setSlider();
          this.setDom();
          this._sliderElement.style.left = "50%";
          this._sliderElement.style.display = "block";
          this._mapContainerElement.scrollLeft = 10000;
          break;
      }
    });
  }
  setDom() {
    this._mainViewer._element.parentNode.parentNode.style.width = "50%";
    this._mainViewer._element.parentNode.style.width = '1920px';
    this._mainViewer._element.parentNode.style.position = 'absolute';
    this._mainViewer._element.parentNode.style.zIndex = '4';
    this._mainViewer._element.parentNode.style.right = '';

    this._secondViewer._element.parentElement.style.width = "100%"
    this._secondViewer._element.parentElement.style.position = 'absolute';
    this._secondViewer._element.parentElement.style.zIndex = '3';
    this._secondViewer._element.parentElement.style.left = '0';
    this._secondViewer._element.parentElement.style.top = '0;';
    this._secondViewer._element.parentElement.style.height = '100%;';

    $('#slider').css('display', 'block');
  }

  resetDom() {
    this._mainViewer._element.parentNode.style.width = '100%';
    this._mainViewer._element.parentNode.style.position = 'absolute';
    this._mainViewer._element.parentNode.style.zIndex = '4';
    // this._mainViewer._element.parentNode.style.right = '50%';
    this._mainViewer._element.parentNode.parentNode.style.overflow = 'hidden';

    this._secondViewer._element.parentElement.style.width = "50%"
    this._secondViewer._element.parentNode.style.position = 'absolute';
    this._secondViewer._element.parentNode.style.height = '100%';
    this._secondViewer._element.parentNode.style.top = '0';
    this._secondViewer._element.parentNode.style.zIndex = '3';
    this._secondViewer._element.parentNode.style.left = '50%';

    $('.tool-bar').css('z-index', 8);

    $('#slider').css('display', 'none');
  }
  setSceneModel(model) {
    if (!Object.values(Linkage.SCENE_MODEL).includes(model)) {
      throw "无效的模式，请使用本类对象stateMap中的状态值";
    }
    this.scneneModel = model;
    switch (model) {
      case Linkage.SCENE_MODEL.SCENE_3D_3D:
        this._mainViewer.scene.mode = 3;
        this._secondViewer.scene.mode = 3;
        break;
      case Linkage.SCENE_MODEL.SCENE_3D_2D:
        this._mainViewer.scene.mode = 3;
        this._secondViewer.scene.mode = 2;
        break;
      case Linkage.SCENE_MODEL.SCENE_2D_3D:
        this._mainViewer.scene.mode = 2;
        this._secondViewer.scene.mode = 3;
        break;
      case Linkage.SCENE_MODEL.SCENE_2D_2D:
        this._mainViewer.scene.mode = 2;
        this._secondViewer.scene.mode = 2;
        break;
    }
  }
  /**
   * @lastUpdateBy : 张瀚
   * @description: 开始复制模式，直到切换了同步状态
   */
  _startCopyTimer() {
    if (this._copyTimer != undefined) {
      //不重复执行
      return;
    }

    this._copyTimer = setTimeout(() => {
      //视角同步
      if (this.mainToSecond) {
        this._copyCamera(this._mainViewer, this._secondViewer);
      } else {
        this._copyCamera(this._secondViewer, this._mainViewer);
      }
      //调整位置标签
      if (this._positionIndicatorID && this._lastEndPosition) {
        let ray = this._mainViewer.scene.camera.getPickRay(
          this._lastEndPosition
        );
        this._nowPosition = Cesium.Ray.getPoint(ray, 10);
      }
      this._copyTimer = undefined;
      this._startCopyTimer();
    }, this.linkInterval);
  }

  /**
   * @author: pwz（潘文周）
   * @description: 主屏副屏同步
   * @param {*} fromViewer
   * @param {*} toViewer
   */
  _copyCamera(fromViewer, toViewer) {
    if (!fromViewer || !toViewer) {
      return;
    }
    let {
      pitch,
      heading,
      roll,
      position
    } = fromViewer.camera;
    toViewer.camera.setView({
      destination: position,
      orientation: {
        heading,
        pitch,
        roll,
      },
    });
  }

  /**
   * @lastUpdateBy : 张瀚
   * @description: 设置位置标记，entity对象，但是目前位置只会修改外面的position
   * @param {*} entityOption
   * @return {*}
   */
  setPositionLabel(entityOption) {
    if (this._positionIndicatorID || entityOption == undefined) {
      //移除位置标签
      this._mainViewer.entities.removeById(this._positionIndicatorID);
      this._secondViewer.entities.removeById(this._positionIndicatorID);
      this._positionIndicatorID = undefined;
      if (entityOption == undefined) {
        //不是重新设置，那就退出
        return;
      }
    }
    let newOption = Object.assign({}, entityOption);
    newOption.position = new Cesium.CallbackProperty(() => {
      return this._nowPosition;
    }, false);
    let mainEntity = new Cesium.Entity(newOption);
    this._positionIndicatorID = mainEntity.id;
    newOption.id = mainEntity.id;
    let secondEntity = new Cesium.Entity(newOption);
    //添加到viewer中
    this._mainViewer.entities.add(mainEntity);
    this._secondViewer.entities.add(secondEntity);
    //隐藏一个
    mainEntity.show = !this.mainToSecond;
    secondEntity.show = this.mainToSecond;
  }
  /**
   * @author: pwz（潘文周）
   * @description: 设置主，副屏幕同步的时间间隔
   * @param {Number} value 单位ms
   * @return {*}
   */
  setLinkInterval(value) {
    this.linkInterval = value;
  }
  /**
   * @author: pwz（潘文周）
   * @description: 创建一个新的Cesium场景
   * @param {String} id 传入需要绑定dome元素的id
   * @param {Object} config 传入场景初始化配置参数
   * @return {Viewer} 返回新创建的场景对象
   */
  static createViewer(id, config) {
    let defaultConfig = {
      contextOptions: {
        webgl: {
          alpha: true,
          depth: false,
          stencil: true,
          antialias: true,
          premultipliedAlpha: true,
          preserveDrawingBuffer: true,
          failIfMajorPerformanceCaveat: true,
        },
        allowTextureFilterAnisotropic: true,
      },
      infoBox: true,
      fullscreenButton: false,
      selectionIndicator: false,
      animation: false, //动画器件
      homeButton: false, //返回初始位置按钮
      geocoder: false, //位置查找工具
      timeline: false, //时间线
      navigationHelpButton: false, //导航帮助按钮
      sceneModePicker: false,
      maximumRenderTimeChange: Infinity,
      baseLayerPicker: false,
    };
    let viewer = new Cesium.Viewer(id, Object.assign(defaultConfig, config));
    //viewer.scene.screenSpaceCameraController.enableInputs = false;
    //判断是否支持图像渲染像素化处理
    if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
      viewer.resolutionScale = window.devicePixelRatio;
    }
    viewer.scene.postProcessStages.fxaa.enabled = true;
    //隐藏版权信息
    viewer._cesiumWidget._creditContainer.style.display = "none";
    //修改鼠标操作习惯
    let agScene = new AGScene(viewer);
    agScene.initializeOperationHabit();
    return viewer;
  }

  /**
   * @lastUpdateBy : 张瀚
   * @description: 设置滑块，卷帘模式时需要启用
   * @return {*}
   */
  _setSlider() {
    var self = this;

    this._sliderElement.removeEventListener(
      "mousedown",
      this._mouseDownListener
    );
    this._sliderElement.removeEventListener(
      "mousedown",
      this._mouseDownListener
    );
    this._sliderElement.addEventListener("mousedown", this._mouseDownListener);
    this._mouseMoveListener = (event) => {
      //移动过程中，不断调整上层地图的宽度
      var right = event.clientX / window.innerWidth;
      self._mainViewer._element.parentNode.parentNode.style.width = (right * 100).toString() + '%';
      // var toolRight = window.innerWidth - event.clientX + 14 + 'px';
      // $('.rt-box').css('right',toolRight);
      self._sliderElement.style.left = `${event.clientX}px`;
    };
    window.removeEventListener("mouseup", this._mouseUpListener);
    window.addEventListener("mouseup", this._mouseUpListener);
  }

  /**
   * @author: pwz（潘文周）
   * @description: 清除
   */
  clear() {
    //移除位置
    this.setPositionLabel();
    //清除定时器
    clearTimeout(this._copyTimer);
    this._mainPickHelper.reset();
    this._secondPickHelper.reset();
    //移除监听
    window.removeEventListener("mousemove", this._mouseMoveListener);
    window.removeEventListener("mouseup", this._mouseUpListener);
    // window.removeEventListener("resize",this._resizeListener);

    this._sliderElement.removeEventListener(
      "mousedown",
      this._mouseDownListener
    );
    this._mainViewer._element.parentNode.style.position = "";
    this._mainViewer._element.parentNode.style.width = "100%";
    this._mainViewer._element.parentNode.style.zIndex = "";
    this._mainViewer._element.parentNode.style.right = "";
    this._mainViewer._element.parentNode.parentNode.style.width = "100%";
    this._mainViewer._element.parentNode.parentNode.style.overflow = "";
    $("#slider").css('display', 'none');
    $("#map").empty();
    $("#map").css({
      'width': '0',
      'height': '0'
    });
    $("#containCesium").css('opacity', 1);
    CIM.secondViewer = null;
  }
}

Linkage.MODEL_TYPE = Object.freeze({
  //复制模式,以鼠标所在viewer为主，复制视角到另一viewer
  COPY: 0,
  //左右分屏模式
  SPLIT_SCREEN: 1,
  //卷帘模式，复制的同时，调整增加一个可以拖动的进度条，可以调整上方的div的宽度
  ROLL: 2,
});

Linkage.SCENE_MODEL = Object.freeze({
  //两个场景都是3d
  SCENE_3D_3D: 0,
  //主屏的3d副屏是2d
  SCENE_3D_2D: 1,
  //主屏的2d副屏是3d
  SCENE_2D_3D: 2,
  SCENE_2D_2D: 3,
});
export default Linkage;